home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
pctim12.zip
/
GCCINT8.C
< prev
next >
Wrap
Text File
|
1995-01-29
|
6KB
|
223 lines
#include <dos.h>
#include <dpmi.h>
#include <pc.h>
#include "gccint8.h"
#define IRQ0 0x8
#define PIT0 0x40
#define PIT1 0x41
#define PIT2 0x42
#define PITMODE 0x43
#define PITCONST 1193180L
#define PIT0DEF 18.2067597
#define KBCTRL 0x61
#define NEW8H 1
static float tick_per_ms = 0.0182068;
static float ms_per_tick = 54.9246551;
static float freq8h = 18.2067597;
static unsigned char flag8h = 0;
static _go32_dpmi_seginfo rm_old_handler,
rm_new_handler,
pm_old_handler,
pm_new_handler;
static _go32_dpmi_registers r,
r1;
volatile int counter_8h;
volatile int counter_reset;
volatile unsigned long int ticks_8h;
void init8h(unsigned int Hz)
{
unsigned int pit0_set,
pit0_value;
if (flag8h != NEW8H) {
disable();
_go32_dpmi_get_protected_mode_interrupt_vector(8, &pm_old_handler);
pm_new_handler.pm_offset = (int) pm_new8h;
pm_new_handler.pm_selector = _go32_my_cs();
_go32_dpmi_chain_protected_mode_interrupt_vector(8, &pm_new_handler);
_go32_dpmi_get_real_mode_interrupt_vector(8, &rm_old_handler);
rm_new_handler.pm_offset = (int) rm_new8h;
_go32_dpmi_allocate_real_mode_callback_iret(&rm_new_handler, &r1);
_go32_dpmi_set_real_mode_interrupt_vector(8, &rm_new_handler);
outportb(PITMODE, 0x36);
pit0_value = PITCONST / Hz;
pit0_set = (pit0_value & 0x00ff);
outportb(PIT0, pit0_set);
pit0_set = (pit0_value >> 8);
outportb(PIT0, pit0_set);
enable();
flag8h = NEW8H;
freq8h = Hz;
counter_8h = 0;
counter_reset = freq8h / PIT0DEF;
tick_per_ms = freq8h / 1000;
ms_per_tick = 1000 / freq8h;
}
}
void quit8h(void)
{
unsigned int pit0_set,
pit0_value;
unsigned long tick;
char *cmostime;
if (flag8h == NEW8H) {
disable();
outportb(PITMODE, 0x36);
outportb(PIT0, 0x00);
outportb(PIT0, 0x00);
_go32_dpmi_set_real_mode_interrupt_vector(8, &rm_old_handler);
_go32_dpmi_set_protected_mode_interrupt_vector(8, &pm_old_handler);
_go32_dpmi_free_real_mode_callback(&rm_new_handler);
enable();
cmostime = get_cmostime();
tick = PIT0DEF *
(
(((float) *cmostime) * 3600) +
(((float) *(cmostime + 1)) * 60) +
(((float) *(cmostime + 2)))
);
biostime(1, tick);
flag8h = 0;
freq8h = PIT0DEF;
counter_reset = freq8h / PIT0DEF;
tick_per_ms = freq8h / 1000;
ms_per_tick = 1000 / freq8h;
}
}
void rm_new8h(void)
{
ticks_8h++;
counter_8h++;
if (counter_8h == counter_reset) {
counter_8h = 0;
memset(&r, 0, sizeof(r));
r.x.cs = rm_old_handler.rm_segment;
r.x.ip = rm_old_handler.rm_offset;
r.x.ss = r.x.sp = 0;
_go32_dpmi_simulate_fcall_iret(&r);
/* Note. You should use "r.x.cs = 0xf000; r.x.ip = 0xfea5;" instead
* of "r.x.cs = rm_old_handler.rm_segment; r.x.ip =
* rm_old_handler.rm_offset;" if your gcc version is older than
* 2.6.3. This is because of a bug in gcc 2.6.0. PCTIMER for gcc was
* first developed under gcc 2.6.0, and it was found that the
* following instructions: "r.x.cs = rm_old_handler.rm_segment;
* r.x.ip = rm_old_handler.rm_offset; r.x.ss = r.x.sp = 0;
* _go32_dpmi_simulate_fcall_iret(&r);" could not call
* rm_old_handler.rm_segment:rm_old_handler.rm_offset correctly.
* Therefore, my solution in PCTIMER 1.1 was to call f000:fea5, which
* is the default handler of int 8h in IBM PC and fully compatible
* BIOSes. Since the bug has been fixed in gcc 2.6.3, the
* "rm_new8h" handler should also be revised. */
} else {
outportb(0x20, 0x20);
}
}
void pm_new8h(void)
{
ticks_8h++;
counter_8h++;
if (counter_8h == counter_reset) {
counter_8h = 0;
} else {
outportb(0x20, 0x20);
}
}
unsigned long time8h(unsigned long start, unsigned long stop)
{
unsigned long duration,
millisec;
if (stop < start)
return 0;
else {
duration = stop - start;
millisec = duration * ms_per_tick;
return millisec;
}
}
void delay8h(unsigned int delayms)
{
unsigned long int delaybegin = 0;
unsigned long int delayend = 0;
unsigned int delaytick;
delaytick = delayms * tick_per_ms;
if (flag8h == NEW8H)
delaybegin = ticks_8h;
else
delaybegin = biostime(0, 0);
do {
if (flag8h == NEW8H)
delayend = ticks_8h;
else
delayend = biostime(0, 0);
} while ((delayend - delaybegin) < delaytick);
}
void sound8h(int freq, int duration)
{
int byte;
unsigned int freq1;
freq1 = PITCONST / freq;
outportb(PITMODE, 0xb6);
byte = (freq1 & 0xff);
outportb(PIT2, byte);
byte = (freq1 >> 8);
outportb(PIT2, byte);
byte = inportb(KBCTRL);
outportb(KBCTRL, (byte | 3));
delay8h(duration);
outportb(KBCTRL, (byte & 0xfc));
}
char *get_cmostime(void)
{
char *buff;
static char buffer[6];
char ch;
buff = buffer;
memset(&r, 0, sizeof(r));
r.h.ah = 0x02;
_go32_dpmi_simulate_int(0x1a, &r);
ch = r.h.ch;
buffer[0] = (char) ((int) (ch & 0x0f) + (int) ((ch >> 4) & 0x0f) * 10);
ch = r.h.cl;
buffer[1] = (char) ((int) (ch & 0x0f) + (int) ((ch >> 4) & 0x0f) * 10);
ch = r.h.dh;
buffer[2] = (char) ((int) (ch & 0x0f) + (int) ((ch >> 4) & 0x0f) * 10);
buffer[3] = r.h.dl;
buffer[4] = (char) (r.x.flags & 0x0001);
buffer[5] = 0x00;
return (buff);
}